﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data.Common;
using System.Data;

namespace Vbyte.SharpOrm.SqlDb
{
    /// <summary>
    /// SQL数据库辅助的抽象层实现
    /// </summary>
    public abstract class SqlDbBase : ISqlDb
    {

        #region ISqlDb 成员

        private string _connectionString;
        /// <summary>
        /// 数据库连接字符串
        /// </summary>
        /// <value></value>
        public virtual string ConnectionString
        {
            get { return _connectionString; }
            set { _connectionString = value; }
        }

        private DbConnection _conn;
        /// <summary>
        /// 获取或设置该实例上的数据库连接
        /// </summary>
        /// <value>数据库连接对象</value>
        public virtual DbConnection CurrentConnection
        {
            get { return _conn; }
            set { _conn = value; }
        }

        /// <summary>
        /// 使用共享数据库连接获取满足条件查询的内容数据表
        /// </summary>
        /// <param name="sharedConn">共享数据库连接对象</param>
        /// <param name="cmd">数据获取操作命令</param>
        /// <returns>通过数据获取命令获取的内容数据表</returns>
        public DataTable GetDataTable(DbConnection sharedConn, DbCommand cmd)
        {
            DataTable dTab = new DataTable("default");
            dTab.Load(GetDataReader(sharedConn, cmd));
            return dTab;
        }


        /// <summary>
        /// 使用共享数据库连接获取满足条件查询的数据只读器
        /// </summary>
        /// <param name="sharedConn">共享数据库连接对象</param>
        /// <param name="cmd">数据获取操作命令</param>
        /// <returns>数据只读器</returns>
        public DbDataReader GetDataReader(DbConnection sharedConn, DbCommand cmd)
        {
            if (cmd.Connection == null) cmd.Connection = sharedConn;
            DbDataReader reader = cmd.ExecuteReader();
            return reader;
        }

        /// <summary>
        /// 对连接对象执行 SQL 语句
        /// </summary>
        /// <param name="sharedConn">共享数据库连接对象</param>
        /// <param name="cmd">数据操作命令</param>
        /// <returns>受影响的行数</returns>
        public int ExecuteNonQuery(DbConnection sharedConn, DbCommand cmd)
        {
            if (cmd.Connection == null) cmd.Connection = sharedConn;
            return cmd.ExecuteNonQuery();
        }

        /// <summary>
        /// 执行cmd命令查询，并返回查询所返回的结果集中第一行的第一列。所有其他的列和行将被忽略。
        /// </summary>
        /// <param name="sharedConn">共享数据库连接对象</param>
        /// <param name="cmd">数据获取操作命令</param>
        /// <returns>第一行的第一列的值</returns>
        public object GetScalar(DbConnection sharedConn, DbCommand cmd)
        {
            if (cmd.Connection == null) cmd.Connection = sharedConn;
            return cmd.ExecuteScalar();
        }

        /// <summary>
        /// 判定是否存在数据库
        /// </summary>
        /// <param name="dbname">数据库名或路径</param>
        /// <returns></returns>
        public abstract bool ExsitsDb(string dbname);

        /// <summary>
        /// 创建数据库
        /// </summary>
        /// <param name="dbname">数据库名或文件路径</param>
        public abstract void CreateDb(string dbname);

        /// <summary>
        /// 创建带密码的数据库(嵌入式数据库适用)
        /// </summary>
        /// <param name="dbname">数据库名或文件路径</param>
        /// <param name="dbpwd">数据库密码</param>
        public abstract void CreateDb(string dbname, string dbpwd);

        /// <summary>
        /// 删除数据库
        /// </summary>
        /// <param name="dbName">数据库名或路径</param>
        public abstract void DropDb(string dbName);

        /// <summary>
        /// 判定是否存在指定表名
        /// </summary>
        /// <param name="tabName">数据库表名</param>
        /// <returns></returns>
        public abstract bool ExistsTable(string tabName);

        /// <summary>
        /// 根据统一表定义创建表
        /// </summary>
        /// <param name="tabDefine">数据表定义</param>
        public abstract void CreateTable(SqlTable tabDefine);

        /// <summary>
        /// 删除数据库中的表
        /// </summary>
        /// <param name="tabName">数据库表名</param>
        public abstract void DropTable(string tabName);

        /// <summary>
        /// 对表的修改，执行原生的SQL语句
        /// </summary>
        /// <param name="NativeSql">原生的SQL语句</param>
        public abstract void AlterTable(string NativeSql);

        /// <summary>
        /// 判定是否存在指定的列名
        /// </summary>
        /// <param name="tabName">数据库表名</param>
        /// <param name="colName">数据表中的列名</param>
        /// <returns></returns>
        public abstract bool ExistsColumn(string tabName, string colName);

        /// <summary>
        /// 在指定表名中添加新的列
        /// </summary>
        /// <param name="tabName">数据库表名</param>
        /// <param name="column">数据列定义</param>
        public abstract void AddColumn(string tabName, SqlTableColumn column);

        /// <summary>
        /// 删除指定表名中的数据列
        /// </summary>
        /// <param name="tabName">数据库表名</param>
        /// <param name="colName">数据表中的列名</param>
        public abstract void DropColumn(string tabName, string colName);

        #endregion

        #region IDisposable 成员

        /// <summary>
        /// 执行与释放或重置非托管资源相关的应用程序定义的任务。
        /// </summary>
        public virtual void Dispose()
        {
            if (_conn != null)
            {
                if (_conn.State != ConnectionState.Closed) _conn.Close();
                _conn.Dispose();
            }
        }

        #endregion
    }
}
